package org.ws.task.web;

import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.ws.task.model.NodeMetadata;
import org.ws.task.model.TaskStatistics;
import org.ws.task.repository.NodeMetadataRepository;
import org.ws.task.repository.TaskRepository;
import org.ws.task.repository.TaskStatisticsRepository;
import org.ws.task.web.vo.TaskTreeNode;

import java.util.Collection;
import java.util.List;
import java.util.Set;

@RequestMapping("/task-manager")
@RestController
public class TaskManagerController {

    /**
     * WorkerName
     *  |--Leader
     *     |--id
     *     |--ip
     *  |--Workers
     * @return
     */
    @GetMapping("/nodes/tree")
    public TaskTreeNode nodes(){
        Set<String> workerNames = TaskRepository.getInstance().taskNames();
        TaskTreeNode taskTreeNode = new TaskTreeNode("TaskNodes");
        List<TaskTreeNode> rootChildren = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(workerNames)){
            for (String workerName : workerNames) {
                TaskTreeNode workerNameNode = new TaskTreeNode(workerName);
                rootChildren.add(workerNameNode);
                List<TaskTreeNode> workerNameChildren = Lists.newArrayList();
                workerNameNode.setChildren(workerNameChildren);

                // leader
                TaskTreeNode leaderNode = new TaskTreeNode("Leader");
                workerNameChildren.add(leaderNode);
                List<TaskTreeNode> leaderChildren = Lists.newArrayList();
                leaderNode.setChildren(leaderChildren);

                NodeMetadata leader = NodeMetadataRepository.getInstance().getLeader();
                TaskTreeNode leaderChildrenNode = new TaskTreeNode(leader.getAddress());
                leaderChildrenNode.setData(leader);
                leaderChildrenNode.setLeader(Boolean.TRUE);
                leaderChildren.add(leaderChildrenNode);

                // workers
                TaskTreeNode workersNode = new TaskTreeNode("Workers");
                workerNameChildren.add(workersNode);

                List<TaskTreeNode> workersChildren = Lists.newArrayList();
                workersNode.setChildren(workersChildren);

                Collection<NodeMetadata> workers = NodeMetadataRepository.getInstance().getActiveWorkerNodes(workerName);
                for (NodeMetadata nodeMetadata : workers) {
                    TaskTreeNode workerNode = new TaskTreeNode(nodeMetadata.getAddress());
                    workerNode.setData(nodeMetadata);
                    workersChildren.add(workerNode);
                }
            }
        }
        taskTreeNode.setChildren(rootChildren);
        return taskTreeNode;
    }

    @GetMapping("/nodes/list")
    public Collection<NodeMetadata> workerNodes(){
        List<NodeMetadata> list = Lists.newArrayList();
        list.add(NodeMetadataRepository.getInstance().getLeader());
        list.addAll(NodeMetadataRepository.getInstance().getWorkers());
        return list;
    }

    @GetMapping("/task/statistics")
    public Collection<TaskStatistics> taskStatistics(){
        List<TaskStatistics> list = Lists.newArrayList();
        Set<String> workerNames = TaskRepository.getInstance().taskNames();
        for (String workerName : workerNames) {
            TaskStatistics taskStatistics = TaskStatisticsRepository.getInstance().getTaskStatistics(workerName);
            list.add(taskStatistics);
        }
        return list;
    }

    @GetMapping("/task/node/statistics")
    public Collection<TaskStatistics> taskNodeStatistics(String workerName){
        List<TaskStatistics> list = Lists.newArrayList();
        Collection<NodeMetadata> workers = NodeMetadataRepository.getInstance().getActiveWorkerNodes(workerName);
        if(CollectionUtils.isNotEmpty(workers)){
            for (NodeMetadata nodeMetadata : workers) {
                TaskStatistics taskStatistics = TaskStatisticsRepository.getInstance().getTaskStatistics(nodeMetadata);
                list.add(taskStatistics);
            }
        }
        return list;
    }

}
